package com.aaa.project.file.service.impl;

import cn.hutool.core.util.StrUtil;
import com.aaa.common.utils.file.FileUploadUtils;
import com.aaa.project.file.config.MinioConfig;
import com.aaa.project.file.service.ISysFileService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

/**
 * Minio 文件存储
 *
 * @author ruoyi
 */
@Service
public class MinioSysFileServiceImpl implements ISysFileService {

    private static final Logger log = LoggerFactory.getLogger(MinioSysFileServiceImpl.class);

    @Value("${minio.path}")
    private String path;

    @Autowired
    private MinioConfig minioConfig;
    @Autowired
    private MinioClient client;

    /**
     * Minio文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        if (file == null || file.isEmpty()) {
            log.warn("File is empty, skip uploading");
            return null;
        }
        InputStream inputStream = null;
        try {
            String fileName = StrUtil.format("{}/{}", path, FileUploadUtils.extractFilename(file));
            inputStream = file.getInputStream();
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            client.putObject(args);
            return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
        } catch (Exception e) {
            log.error("Minio Failed to upload file", e);
            throw new RuntimeException("Minio Failed to upload file", e);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    @Override
    public void deleteFile(String fileUrl) {
        try {
            if (StrUtil.isBlank(fileUrl)) {
                log.warn("File URL is blank, skip deleting");
                return;
            }
            // 解析URL，提取bucket和object
            String baseUrl = StrUtil.format("{}/{}/", minioConfig.getUrl(), minioConfig.getBucketName());
            if (fileUrl.startsWith(baseUrl)) {
                String object = fileUrl.substring(baseUrl.length());
                // 调用Minio删除接口
                client.removeObject(io.minio.RemoveObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(object)
                        .build());
                log.info("Minio file deleted successfully: {}", fileUrl);
            } else {
                log.error("Invalid file URL: {}", fileUrl);
                throw new IllegalArgumentException("Invalid file URL");
            }
        } catch (Exception e) {
            log.error("Minio Failed to delete file: {}", fileUrl, e);
            throw new RuntimeException("Minio Failed to delete file", e);
        }
    }

    @Override
    public String uploadFile(InputStream inputStream, String fileName) throws Exception {
        if (inputStream == null) {
            log.warn("File is empty, skip uploading");
            return null;
        }
        try {
            String fileNameStr = StrUtil.format("{}/{}", path, fileName);
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileNameStr)
                    .stream(inputStream, inputStream.available(), -1)
                    .build();
            client.putObject(args);
            return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileNameStr;
        } catch (Exception e) {
            log.error("Minio Failed to upload file", e);
            throw new RuntimeException("Minio Failed to upload file", e);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }
}
